﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Kgb.Model.Models;
using Kgb.Service.Repository;
using Kgb.Service.Repository.Interface;
using System.Net;

namespace Kgb.Service.Controllers
{
    public class RoomsController : ApiController
    {
        //static readonly
        private IRoomRepository _repository = new RoomRepository();

        public RoomsController()
        { 
            _repository = new RoomRepository();
        }

        public IQueryable<Room> GetAllRooms()
        {
            return _repository.GetAll();
        }

        public Room GetRoom(int id)
        {
            Room room = _repository.Get(id);
            if (room == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return room;
        }

        [HttpGet]
        public IQueryable<Location> Locations(int id, int locationId)
        {
            Room room = _repository.Get(id);
            if (room == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            LocationRepository locationRepository = new LocationRepository();

            var result = locationRepository.GetAllByRoom(room.Id); 

            if (locationId > 0)
            {
                return result.Where(s=>s.Id == locationId);
            }
            else
            {
                return result;
            }
        }

        public HttpResponseMessage<Room> PostRoom(Room room)
        {
            room = _repository.Add(room);
            var response = new HttpResponseMessage<Room>(room, HttpStatusCode.Created);

            string uri = Url.Route(null, new { id = room.Id });
            response.Headers.Location = new Uri(Request.RequestUri, uri);
            return response;
        }

        public HttpResponseMessage<Room> AccessRoom(int roomId, int playerId, string sessionId)
        {
            Room room = _repository.Get(roomId);
            if (room == null)
                throw new HttpResponseException("Invalid roomId", HttpStatusCode.NotFound);

            if (room.State == "cheia")
                throw new HttpResponseException("A sala está cheia e não pode ser utilizada!", HttpStatusCode.Forbidden);

            if (room.State == "aguardando" || room.State == "jogando")
                throw new HttpResponseException("A sala está em jogo e não pode ser utilizada!", HttpStatusCode.Forbidden);

            var playerRepository = new PlayerRepository();
            Player player = playerRepository.Get(playerId);
            
            if (player == null)
                throw new HttpResponseException("Invalid playerId", HttpStatusCode.NotFound);

            if (!player.ValidateSession(sessionId))
                throw new HttpResponseException("SessionId inválida!", HttpStatusCode.Forbidden);

            var locationRepository = new LocationRepository();

            var validPlayer = locationRepository.GetByPlayer(player);

            if (validPlayer != null)
                throw new HttpResponseException( String.Format( "O jogador já está ocupando o lugar {0} da sala {1}."
                                                             , validPlayer.Id, validPlayer.RoomId
                                                             )
                                               , HttpStatusCode.Forbidden
                                               );

            var locations = locationRepository.GetAllByRoom(room.Id);

            var location = locations.Where(x => x.State == "livre").FirstOrDefault();
            var locationsState = locations.Where(x=>x.State=="ocupada").Count();
            if (location == null || locationsState >= 6)
            {
                room.State = "cheia";
                throw new HttpResponseException("A sala está cheia e não pode ser utilizada!", HttpStatusCode.Forbidden);
            }

            if (locationsState == 5)
            {
                room.State = "cheia";                
            }

            player.RoomId = room.Id;
            player.State = "waiting";
            location.State = "ocupada";
            location.LocationPlayer = player; 

            var response = new HttpResponseMessage<Room>(room, HttpStatusCode.Accepted);

            string uri = Url.Route(null, new { id = room.Id });
            response.Headers.Location = new Uri(Request.RequestUri, uri);
            return response;
        }

        public void PutRoom(int id, Room room)
        {
            room.Id = id;
            if (!_repository.Update(room))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }

        public HttpResponseMessage DeleteRoom(int id)
        {
            _repository.Remove(id);
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }
}
